const { src, dest, series, parallel, watch } = require('gulp')

const del = require('del')

const browserSync = require('browser-sync') //开发服务插件，提供热更新

const bs = browserSync.create()

const loadPlugins = require('gulp-load-plugins')

const plugins = loadPlugins()//自动加载插件
// const cleanCss = require('gulp-clean-css')
// const plugins.sass = require('gulp-sass') //scss转换
// const plugins.babel = require('gulp-babel') //es6语法转换
// const plugins.swig = require('gulp-swig') //swig模板转换
// const plugins.imagemin = require('gulp-imagemin')



const data = {
  menus: [
    {
      name: 'Home',
      icon: 'aperture',
      link: 'index.html'
    },
    {
      name: 'Features',
      link: 'features.html'
    },
    {
      name: 'About',
      link: 'about.html'
    },
    {
      name: 'Contact',
      link: '#',
      children: [
        {
          name: 'Twitter',
          link: 'https://twitter.com/w_zce'
        },
        {
          name: 'About',
          link: 'https://weibo.com/zceme'
        },
        {
          name: 'divider'
        },
        {
          name: 'About',
          link: 'https://github.com/zce'
        }
      ]
    }
  ],
  pkg: require('./package.json'),
  date: new Date()
}

const clean = () => {
  return del(['temp', 'dist'])
}

//样式编译任务
const style = () => {
  return src('src/assets/styles/**.scss', { base: 'src' }) //base 能保留src后面的目录结构
    .pipe(plugins.sass({ outputStyle: 'expanded' })) //outputStyle: 'expanded' 完全展开样式中的大括号使结尾的}换行
    .pipe(dest('temp'))
}

//脚本的编译
const scripts = () => {
  return src('src/assets/scripts/**.js', { base: 'src' })
    .pipe(plugins.babel({ presets: ['@babel/preset-env'] })) //不配preset会出现一些转换失败的情况，babel只是一个转换平台，而真正干活的是插件比如preset-env
    .pipe(dest('temp'))
}

//编译页面模板
const page = () => {
  return src('src/**/*.html', { base: 'src' })
    .pipe(plugins.swig({ data, defaults: { cache: false } })) // cache设置为false防止模板缓存导致页面不能及时更新
    .pipe(dest('temp'))
}

const image = () => {
  return src('src/assets/images/**', { base: 'src' })
    .pipe(plugins.imagemin())
    .pipe(dest('temp'))
}

const font = () => {
  return src('src/assets/fonts/**', { base: 'src' })
    .pipe(plugins.imagemin()) //字体文件中也会有svg格式的，所以也能用imagemin，而且imagemin不会去压缩处理不了的格式文件
    .pipe(dest('temp'))
}

//拷贝额外的文件，比如public
const extra = () => {
  return src('public/**', { base: 'public' })
    .pipe(dest('temp'))
}

//启动服务任务
const serve = () => {
  watch('src/assets/styles/**.scss', style) //监视样式文件
  watch('src/assets/scripts/**.js', scripts)
  watch('src/*.html', page)
  //因为开发阶段以下文件的编译没有实质的意义，因此可以先不编译，减少构建任务
  // watch('src/assets/images/**', image)
  // watch('src/assets/font/**', font)
  // watch('public/**', extra)

  //监听三个资源文件的变化，使用reload重载页面，达到热更新的效果
  watch([
    'src/assets/images/**',
    'src/assets/font/**',
    'public/**'
  ], bs.reload)
  bs.init({
    notify: false, //设置提示
    port: 2080,//设置端口
    open: true,//是否自动打开浏览器，默认为true
    files: 'temp/**', //监听需要自动更新的文件
    server: {
      baseDir: ['temp', 'src', 'public'],//设置路径会从左往后查找文件
      routes: { //优先baseDir
        '/node_modules': 'node_modules' //临时路径指向到根目录下的文件
      }
    }
  })
}

//处理打包完后html里的文件引用，因为当有用到三方插件的时候，打包出来的html文件引用路径是在node_modules里的，而temp里是不存在这个路径的，
//通过useref这个插件，利用打包注释，将文件统一打包到注释生成的路径里来实现文件引用
const useref = () => {
  return src('temp/*.html', { base: 'temp' })
    .pipe(plugins.useref({ searchPath: ['temp', '.'] }))
    //对js css html进行压缩gulp-htmlmin gulp-uglify gulp-clean-css
    .pipe(plugins.if(/\.js$/, plugins.uglify()))
    .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
    .pipe(plugins.if(/\.html$/, plugins.htmlmin({ collapseWhitespace: true, minifyCSS: true, minifyJS: true })))
    .pipe(dest('dist'))
}

const compile = parallel(style, scripts, page)

//上线之前执行的任务
const build = series(clean, parallel(series(compile, useref), image, font, extra))

const develop = series(compile, serve)

module.exports = {
  build,
  develop,
  clean
}